package com.vast.admin.service;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.vast.admin.api.BestsignOpenApi;
import com.vast.admin.api.WechatApi;
import com.vast.admin.api.entity.*;
import com.vast.admin.api.response.*;
import com.vast.admin.entity.BestsignCallback;
import com.vast.admin.entity.Customer;
import com.vast.admin.entity.RealnameLog;
import com.vast.admin.entity.ValidateCode;
import com.vast.admin.entity.enums.OperatorEum;
import com.vast.admin.entity.enums.QueryOrderEnum;
import com.vast.admin.entity.weChat.WxRealNameByFace;
import com.vast.admin.entity.weChat.WxRealNameByIdentity3;
import com.vast.admin.entity.weChat.WxRealNameByIdentity4;
import com.vast.admin.entity.weChat.WxRealNameIdentity4Verify;
import com.vast.admin.mapper.CustomerMapper;
import com.vast.admin.utils.QueryBuilder;
import com.vast.admin.utils.TableFieldColumnsUtils;
import com.vast.common.core.domain.entity.SysUser;
import com.vast.common.constant.MessageCode;
import com.vast.common.core.domain.Result;
import com.vast.system.exception.BusinessException;
import com.vast.system.utils.SmsUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
public class CustomerService extends ServiceImpl<CustomerMapper, Customer> {

    @Autowired
    private BestsignOpenApi bestsignOpenApi;

    @Value("${ssqApi.afterRealNameByFaceUrl}")
    private String afterRealNameByFaceUrl;

    @Autowired
    private WechatApi wechatApi;

    @Autowired
    private ContractService contractService;

    @Autowired
    private AsyncService asyncService;

    @Autowired
    private SmsUtils smsUtils;

    @Autowired
    private RealnameLogService realnameLogService;

    @Autowired
    private BestsignCallbackService bestsignCallbackService;

    private static final ConcurrentHashMap<String, ValidateCode> VALIDATE_CODE_CONCURRENT_HASH_MAP = new ConcurrentHashMap<>();

    public IPage<Customer> queryList(Page<Customer> page, boolean listMode, String queryItems, String orderField, QueryOrderEnum order) {
        QueryWrapper<Customer> queryWrapper = new QueryWrapper<>();
        Map<String, String> fieldColumns = TableFieldColumnsUtils.getInstance().getFieldTableColumns(Customer.class);
        if (listMode) {
            // size 小于 0 不在查询 total 及分页，自动调整为列表模式。
            // 注意！！这个地方自己控制好！！
            page.setSize(-1);
        }
        if (!StringUtils.isEmpty(queryItems)) {
            List<QueryBuilder> queryBuilders = new ArrayList<>();
            String[] queryItemArr = queryItems.split(";");
            if(queryItemArr.length > 0){
                for (String queryItemStr : queryItemArr) {
                    String[] itemArr = queryItemStr.split(",");
                    if(itemArr.length == 3){
                        String as = itemArr[1];
                        String params = itemArr[2];
                        if(!StringUtils.isEmpty(params)){
                            queryBuilders.add(new QueryBuilder(itemArr[0], OperatorEum.valueOf(as),itemArr[2]));
                        }
                    }
                }
            }

            for (QueryBuilder queryBuilder : queryBuilders) {
                //查询字段
                String field = queryBuilder.getField();
                //查询参数值
                String params = queryBuilder.getParams();
                if (fieldColumns.containsKey(field) && !StringUtils.isEmpty(params)) {
                    //表属性
                    String tableColumn = fieldColumns.get(field);
                    if (queryBuilder.getAs() == OperatorEum.EQ) {
                        queryWrapper.eq(tableColumn, params);
                    }else if(queryBuilder.getAs() == OperatorEum.LIKE){
                        queryWrapper.like(tableColumn, params);
                    }else if(queryBuilder.getAs() == OperatorEum.LIKELEFT){
                        queryWrapper.likeLeft(tableColumn, params);
                    }else if(queryBuilder.getAs() == OperatorEum.LIKERIGHT){
                        queryWrapper.likeRight(tableColumn, params);
                    }else if(queryBuilder.getAs() == OperatorEum.GE){
                        queryWrapper.ge(tableColumn, params);
                    }else if(queryBuilder.getAs() == OperatorEum.LE){
                        queryWrapper.le(tableColumn, params);
                    }
                }
            }
        }
        if (!StringUtils.isEmpty(orderField)) {
            String[] orderByColumns = orderField.split(",");
            String queryOrderByColumns = "";
            if (orderByColumns.length > 0) {
                StringBuilder sb = new StringBuilder();
                for (String orderByColumn : orderByColumns) {
                    if (fieldColumns.containsKey(orderByColumn)) {
                        sb.append(fieldColumns.get(orderByColumn)).append(",");
                    }
                }
                if (sb.length() > 0) {
                    queryOrderByColumns = sb.deleteCharAt(sb.length() - 1).toString();
                }
            }
            if (!StringUtils.isEmpty(queryOrderByColumns)) {
                if(order == null){
                    order = QueryOrderEnum.ASC;
                }
                if (order == QueryOrderEnum.ASC) {
                    queryWrapper.orderByAsc(queryOrderByColumns);
                } else if (order == QueryOrderEnum.DESC) {
                    queryWrapper.orderByDesc(queryOrderByColumns);
                }
            }

        }
        return baseMapper.selectPage(page, queryWrapper);
    }

    public boolean addOrUpdate(SysUser manager, Customer bean) {
        if (bean.getId() == null) {
            bean.setCreateBy(manager.getUserId());
            bean.setUpdateBy(manager.getUserId());
            bean.setCreateTime(DateTime.now());
            bean.setUpdateTime(DateTime.now());
            bean.setValid(1);

            baseMapper.insert(bean);

            return true;
        } else {
            bean.setUpdateBy(manager.getUserId());
            bean.setUpdateTime(DateTime.now());
            bean.setValid(1);
            baseMapper.updateById(bean);
            return true;

        }
    }

    public Customer info(SysUser manager, Long id) {
        Customer bean = baseMapper.selectById(id);
        return bean;
    }


    public boolean delete(SysUser manager, Long[] ids) {

        List<Long> idsList = java.util.Arrays.asList(ids);
        int count = baseMapper.deleteBatchIds(idsList);

        return count == ids.length;

    }


    /**
     * 添加客户信息
     * @param customer
     */
    public void addCustomer(Customer customer) {
        Customer tmp = getCustomerByWxId(customer.getWxId());
        if (!isSubscribe(customer.getWxId())) {
            throw new BusinessException("未关注微信公众号，无法注册");
        }
        if (isRegister(customer.getWxId(), customer.getMobile())) {
            throw new BusinessException("手机号" + customer.getMobile() + "已被注册");
        }

        if (tmp == null) {
            //新注册用户
            customer.setAccount(UUID.randomUUID().toString().replaceAll("-", ""));
            regBestsignUser(customer);
            super.save(customer);
        } else {
            //已存在用户，修改
            if (tmp.getRealnameStatus().intValue() == 1) {
                throw new BusinessException("已通过实名认证，无法修改");
            } else {
                Customer updateEntity = new Customer();
                updateEntity.setId(tmp.getId());
                updateEntity.setName(customer.getName());
                updateEntity.setMobile(customer.getMobile());
                updateEntity.setEmail(customer.getEmail());
                updateEntity.setAddr(customer.getAddr());
                updateEntity.setEmergencyName(customer.getEmergencyName());
                updateEntity.setEmergencyPhone(customer.getEmergencyPhone());
                super.updateById(updateEntity);
            }

        }
    }

    /**
     * 判断当前手机号是否已被其他微信号注册
     * @param wxId
     * @param phone
     * @return
     */
    private boolean isRegister(String wxId, String phone) {
        QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
        customerQueryWrapper.eq(Customer.COL_MOBILE, phone)
                .ne(Customer.COL_WX_ID, wxId);
        return super.count(customerQueryWrapper) > 0;
    }

    /**
     * 注册上上签用户
     * @param customer
     */
    private void regBestsignUser(Customer customer) {
        RegUser regUser = new RegUser();
        regUser.setName(customer.getName());
        regUser.setAccount(customer.getAccount());
        bestsignOpenApi.personalReg(regUser);
    }

    /**
     * 申请上上签证书
     * @param wxId
     */
    public void applyCert(String wxId) {
        Customer customer = getCustomerByWxId(wxId);
        if (customer == null) {
            throw new BusinessException(new Result(MessageCode.ERROR, "未查询到用户"));
        }
        if (customer.getRealnameStatus().intValue() != 1) {
            throw new BusinessException(new Result(MessageCode.ERROR, "实名认证未通过"));
        }
        if (customer.getBestsignTokenStatus() == null ||  customer.getBestsignTokenStatus() != 5) {
            BestsignAccount bestsignAccount = new BestsignAccount();
            bestsignAccount.setAccount(customer.getAccount());
            BestsignResponse<ApplyCertResponse> bestsignResponse = bestsignOpenApi.applyCert(bestsignAccount);
            Customer updateEntity = new Customer();
            updateEntity.setId(customer.getId());
            updateEntity.setBestsignTokenStatus(5);
            updateEntity.setCertId(bestsignResponse.getData().getCertId());
            super.updateById(updateEntity);
        }
        //实名认证之后开始签署合同流程
        if (StringUtils.hasText(customer.getContractId())) {
            String[] contractIds = customer.getContractId().split(",");
            for (String contractId : contractIds) {
                if (StringUtils.hasText(contractId)) {
                    QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
                    customerQueryWrapper.ne(Customer.COL_REALNAME_STATUS, 1)
                            .like(Customer.COL_CONTRACT_ID, "," + contractId +",");
                    if (super.count(customerQueryWrapper) == 0) {
                        try {
                            synchronized (contractId) {
                                contractService.uploadContract(Long.parseLong(contractId));
                            }
                        } catch (Exception e) {
                            log.error("合同【contractId= " + contractId + "】上传上上签失败", e);
                            //修改合同状态
                            contractService.changeContractStatusFail(Long.parseLong(contractId));
                        }
                    }

                }
            }
        }
    }


    /**
     * 银行卡四要素认证
     * @param wxRealNameByIdentity4
     */
    public RealNameByIdentity4Response realNameByIdentity4(WxRealNameByIdentity4 wxRealNameByIdentity4) {
        Customer customer = getCustomerByWxId(wxRealNameByIdentity4.getWxId());
        if (customer.getRealnameStatus().intValue() == 1) {
            throw new BusinessException(new Result(MessageCode.ERROR, "实名认证已通过"));
        }
        RealNameByIdentity4 realNameByIdentity4 = new RealNameByIdentity4();
        realNameByIdentity4.setAccount(customer.getAccount());
        realNameByIdentity4.setName(customer.getName());
        realNameByIdentity4.setIdentity(wxRealNameByIdentity4.getIdentity());
        realNameByIdentity4.setMobile(wxRealNameByIdentity4.getMobile());
        realNameByIdentity4.setBankCard(wxRealNameByIdentity4.getBankCard());
        String loginfo = "用户【" + realNameByIdentity4.getName() + "】身份证【 " + realNameByIdentity4.getIdentity() + "】进行银行卡四要素实名认证，手机号： " + realNameByIdentity4.getMobile() + "，银行卡号：" + realNameByIdentity4.getBankCard() + "，请求发送手机验证码";
        //记录实名日志
        saveRealnameLog(customer, loginfo);

        String code = SmsUtils.generateValidateCode();
        smsUtils.sendSmsValidateCode(realNameByIdentity4.getMobile(), code);
        VALIDATE_CODE_CONCURRENT_HASH_MAP.put(realNameByIdentity4.getMobile(), new ValidateCode(realNameByIdentity4.getMobile(), code, new Date()));
//        RealNameByIdentity4Response realNameByIdentity4Response = bestsignOpenApi.realNameByIdentity4(realNameByIdentity4).getData();
//        if ("1".equals(realNameByIdentity4Response.getResult())) {
//            //更新客户信息
//            Customer updateEntity = new Customer();
//            updateEntity.setId(customer.getId());
//            updateEntity.setBankCard(wxRealNameByIdentity4.getBankCard());
//            updateEntity.setIdentity(wxRealNameByIdentity4.getIdentity());
//            super.updateById(updateEntity);
//        }
        //更新客户信息
        Customer updateEntity = new Customer();
        updateEntity.setId(customer.getId());
        updateEntity.setBankCard(wxRealNameByIdentity4.getBankCard());
        updateEntity.setIdentity(wxRealNameByIdentity4.getIdentity());
        super.updateById(updateEntity);
        return new RealNameByIdentity4Response();
    }

    /**
     * 检验短信验证码 5分钟有效期
     * @param phone
     * @param code
     * @return
     */
    private boolean checkValidateCode(String phone, String code) {
        if (VALIDATE_CODE_CONCURRENT_HASH_MAP.contains(phone)) {
            ValidateCode validateCode = VALIDATE_CODE_CONCURRENT_HASH_MAP.get(phone);
            if (validateCode.getCode().equals(code) && (System.currentTimeMillis() - validateCode.getDate().getTime()) < 5 * 60 * 1000) {
                return true;
            }
        }
        return false;
    }

    /**
     * 银行卡四要素认证结果
     * @param wxRealNameIdentity4Verify
     */
    @Transactional
    public Result<Void> realNameIdentity4Verify(WxRealNameIdentity4Verify wxRealNameIdentity4Verify) {
        Customer customer = getCustomerByWxId(wxRealNameIdentity4Verify.getWxId());
        RealNameIdentity4Verify realNameIdentity4Verify = new RealNameIdentity4Verify();
        BeanUtils.copyProperties(wxRealNameIdentity4Verify, realNameIdentity4Verify);
        String smsCodeCheckLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameIdentity4Verify.getIdentity() + "】进行银行卡四要素实名认证，手机号：" + wxRealNameIdentity4Verify.getMobile() + "，银行卡号：" + wxRealNameIdentity4Verify.getBankCard() + "，手机验证码：" + wxRealNameIdentity4Verify.getVcode() + "，请求验证手机验证码";
        saveRealnameLog(customer, smsCodeCheckLog);
        //验证短信验证码
        if (checkValidateCode(wxRealNameIdentity4Verify.getMobile(), wxRealNameIdentity4Verify.getVcode())) {
            String errorSmsCodeLog = "短信验证码错误，实名认证失败";
            saveRealnameLog(customer, errorSmsCodeLog);
            return new Result<>(MessageCode.ERROR, "短信验证码错误");
        }

        RealNameByIdentity4 realNameByIdentity4 = new RealNameByIdentity4();
        BeanUtils.copyProperties(wxRealNameIdentity4Verify, realNameByIdentity4);
        realNameByIdentity4.setName(customer.getName());
        BestsignResponse<RealNameIdentity4VerifyResponse> bestsignResponse = bestsignOpenApi.realNameIdentity4VerifyWithoutSmsCode(realNameByIdentity4);
        if ("1".equals(bestsignResponse.getData().getResult())) {
            //认证成功
            String successRealnameLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameIdentity4Verify.getIdentity() + "】进行银行卡四要素实名认证，手机号：" + wxRealNameIdentity4Verify.getMobile() + "，银行卡号：" + wxRealNameIdentity4Verify.getBankCard() + "，手机验证码：" + wxRealNameIdentity4Verify.getVcode() + "，短信验证成功，实名认证通过";
            saveRealnameLog(customer, successRealnameLog);
            //更新实名认证状态及客户信息
            updateRealnameStatusByWxId(1, wxRealNameIdentity4Verify.getWxId(), 1, wxRealNameIdentity4Verify.getIdentity(), wxRealNameIdentity4Verify.getBankCard());
            asyncService.setPersonalCredential(getCustomerByWxId(wxRealNameIdentity4Verify.getWxId()));
            return Result.SUCCESS;
        } else {
            //认证失败
            String errorLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameIdentity4Verify.getIdentity() + "】进行银行卡四要素实名认证，手机号：" + wxRealNameIdentity4Verify.getMobile() + "，银行卡号：" + wxRealNameIdentity4Verify.getBankCard() + "，手机验证码：" + wxRealNameIdentity4Verify.getVcode() + "，实名认证失败，原因：" + bestsignResponse.getData().getMsg();
            saveRealnameLog(customer, errorLog);
            updateRealnameStatusByWxId(3, wxRealNameIdentity4Verify.getWxId(), 0, null, null);
            return new Result<>(MessageCode.ERROR, bestsignResponse.getData().getMsg());
        }
    }

    /**
     * 实名认证日志记录
     * @param customer
     * @param logInfo
     */
    private void saveRealnameLog(Customer customer, String logInfo) {
        log.info(logInfo);
        RealnameLog realnameLog = new RealnameLog();
        realnameLog.setCustomerId(customer.getId());
        realnameLog.setName(customer.getName());
        realnameLog.setLog(logInfo);
        realnameLog.setDate(new Date());
        realnameLogService.save(realnameLog);
    }

    /**
     * 手机号三要素
     * @return
     */
    public String realNameByIdentity3(WxRealNameByIdentity3 wxRealNameByIdentity3) {
        Customer customer = getCustomerByWxId(wxRealNameByIdentity3.getWxId());
        if (customer.getRealnameStatus().intValue() == 1) {
            throw new BusinessException(new Result(MessageCode.ERROR, "实名认证已通过"));
        }
//        RealNameByIdentity3 realNameByIdentity3 = new RealNameByIdentity3();
//        realNameByIdentity3.setAccount(customer.getAccount());
//        realNameByIdentity3.setName(customer.getName());
//        realNameByIdentity3.setIdentity(wxRealNameByIdentity3.getIdentity());
//        realNameByIdentity3.setMobile(wxRealNameByIdentity3.getMobile());
//        BestsignResponse<RealNameByIdentity3Response> bestsignResponse = bestsignOpenApi.realNameByIdentity3(realNameByIdentity3);
        String smsCodeCheckLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameByIdentity3.getIdentity() + "】进行手机号三要素实名认证，手机号：" + wxRealNameByIdentity3.getMobile() + "，请求验证手机验证码";
        saveRealnameLog(customer, smsCodeCheckLog);
        String code = SmsUtils.generateValidateCode();
        smsUtils.sendSmsValidateCode(wxRealNameByIdentity3.getMobile(), code);
        VALIDATE_CODE_CONCURRENT_HASH_MAP.put(wxRealNameByIdentity3.getMobile(), new ValidateCode(wxRealNameByIdentity3.getMobile(), code, new Date()));
        //更新客户信息
        Customer updateEntity = new Customer();
        updateEntity.setId(customer.getId());
        updateEntity.setIdentity(wxRealNameByIdentity3.getIdentity());
        super.updateById(updateEntity);
        return "SUCCESS";
    }

    /**
     * 手机号三要素认证结果
     * @param wxRealNameIdentity4Verify
     */
    @Transactional
    public Result<Void> realNameIdentity3Verify(WxRealNameIdentity4Verify wxRealNameIdentity4Verify) {
        Customer customer = this.getCustomerByWxId(wxRealNameIdentity4Verify.getWxId());
        String smsCodeCheckLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameIdentity4Verify.getIdentity() + "】进行个人三要素实名认证，手机号：" + wxRealNameIdentity4Verify.getMobile() + "，手机验证码：" + wxRealNameIdentity4Verify.getVcode() + "，请求验证手机验证码";
        saveRealnameLog(customer, smsCodeCheckLog);
        //验证短信验证码
        if (checkValidateCode(wxRealNameIdentity4Verify.getMobile(), wxRealNameIdentity4Verify.getVcode())) {
            String errorSmsCodeLog = "短信验证码错误，实名认证失败";
            saveRealnameLog(customer, errorSmsCodeLog);
            return new Result<>(MessageCode.ERROR, "短信验证码错误");
        }

        RealNameByIdentity3 realNameByIdentity3 = new RealNameByIdentity3();
        BeanUtils.copyProperties(wxRealNameIdentity4Verify, realNameByIdentity3);
        realNameByIdentity3.setName(customer.getName());
        BestsignResponse<RealNameIdentity3VerifyResponse> bestsignResponse = bestsignOpenApi.realNameIdentity3VerifyWithoutSmsCode(realNameByIdentity3);
        if ("1".equals(bestsignResponse.getData().getResult())) {
            //认证成功

            String successRealnameLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameIdentity4Verify.getIdentity() + "】进行个人三要素实名认证，手机号：" + wxRealNameIdentity4Verify.getMobile() + "，手机验证码：" + wxRealNameIdentity4Verify.getVcode() + "，短信验证成功，实名认证通过";
            saveRealnameLog(customer, successRealnameLog);
            //更新实名认证状态及客户信息
            updateRealnameStatusByWxId(1, wxRealNameIdentity4Verify.getWxId(), 2, wxRealNameIdentity4Verify.getIdentity(), null);
            asyncService.setPersonalCredential(getCustomerByWxId(wxRealNameIdentity4Verify.getWxId()));
            return Result.SUCCESS;
        } else {
            //认证失败
            String errorLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameIdentity4Verify.getIdentity() + "】进行个人三要素实名认证，手机号：" + wxRealNameIdentity4Verify.getMobile() + "，手机验证码：" + wxRealNameIdentity4Verify.getVcode() + "，实名认证失败，原因：" + bestsignResponse.getData().getMsg();
            saveRealnameLog(customer, errorLog);

            updateRealnameStatusByWxId(4, wxRealNameIdentity4Verify.getWxId(), 0, null, null);
            return new Result<>(MessageCode.ERROR, bestsignResponse.getData().getMsg());
        }
    }

    /**
     * 刷脸认证
     * @param wxRealNameByFace
     * @return
     */
    public RealNameByFaceResponse realNameByFace(WxRealNameByFace wxRealNameByFace) {
        Customer customer = getCustomerByWxId(wxRealNameByFace.getWxId());
        if (customer.getRealnameStatus().intValue() == 1) {
            throw new BusinessException(new Result(MessageCode.ERROR, "实名认证已通过"));
        }

        String smsCodeCheckLog = "用户【" + customer.getName() + "】身份证【" + wxRealNameByFace.getIdentity() + "】进行刷脸实名认证";
        saveRealnameLog(customer, smsCodeCheckLog);

        String sid = UUID.randomUUID().toString();
        RealNameByFace realNameByFace = new RealNameByFace();
        realNameByFace.setAccount(customer.getAccount());
        realNameByFace.setIdentity(wxRealNameByFace.getIdentity());
        realNameByFace.setName(customer.getName());
        realNameByFace.setSid(sid);
        realNameByFace.setReturnUrl(afterRealNameByFaceUrl);
        BestsignResponse<RealNameByFaceResponse> bestsignResponse = bestsignOpenApi.realNameByFace(realNameByFace);
        //更新客户信息
        Customer updateEntity = new Customer();
        updateEntity.setId(customer.getId());
        updateEntity.setFaceSid(sid);
        updateEntity.setIdentity(wxRealNameByFace.getIdentity());
        super.updateById(updateEntity);
        return bestsignResponse.getData();
    }

    /**
     * 刷脸认证结果
     * @param realNameByFaceVerify
     */
    public boolean realNameByFaceVerify(RealNameByFaceVerify realNameByFaceVerify) {
        BestsignCallback bestsignCallback = new BestsignCallback();
        bestsignCallback.setCreateTime(new Date());
        bestsignCallback.setContent(new Gson().toJson(realNameByFaceVerify));
        bestsignCallbackService.save(bestsignCallback);
        QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
        customerQueryWrapper.eq(Customer.COL_FACE_SID, realNameByFaceVerify.getSid());
        Customer customer = super.getOne(customerQueryWrapper);
        if (customer != null) {
            if ("1".equals(realNameByFaceVerify.getVerifyResult())) {
                //认证成功

                String smsCodeCheckLog = "用户【" + customer.getName() + "】身份证【" + customer.getIdentity() + "】进行刷脸实名认证通过，bizNo：" + realNameByFaceVerify.getBizNo();
                saveRealnameLog(customer, smsCodeCheckLog);
                //更新实名认证状态及客户信息
                updateRealnameStatusByWxId(1, customer.getWxId(), 3, customer.getIdentity(), null);
                asyncService.setPersonalCredential(customer);
                return true;
            } else {
                //认证失败

                String smsCodeCheckLog = "用户【" + customer.getName() + "】身份证【" + customer.getIdentity() + "】进行刷脸实名认证失败";
                saveRealnameLog(customer, smsCodeCheckLog);
                updateRealnameStatusByWxId(2, customer.getWxId(), 0, null, null);
                return false;
            }
        }
        return false;
    }

    /**
     * 通过微信id查询
     * @param wxId
     * @return
     */
    public Customer getCustomerByWxId(String wxId) {
        QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
        customerQueryWrapper.eq(Customer.COL_WX_ID, wxId);
        return super.getOne(customerQueryWrapper);
    }

    /**
     * 通过手机号查询
     * @param phone
     * @return
     */
    public Customer getCustomerByPhone(String phone) {
        QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
        customerQueryWrapper.eq(Customer.COL_MOBILE, phone);
        return super.getOne(customerQueryWrapper);
    }

    /**
     * 修改实名认证状态 更新客户信息
     * @param status 实名认证状态（0未认证 1已认证 2认证失败 3银行卡四要素失败 4手机号三要素失败）
     * @param wxId
     * @param realnameType 实名认证方式（1银行卡四要素 2手机号三要素 3刷脸认证）
     * @param identity 身份证号
     * @param bankCard 银行卡号
     */
    private void updateRealnameStatusByWxId(Integer status, String wxId, Integer realnameType, String identity, String bankCard) {
        UpdateWrapper<Customer> customerUpdateWrapper = new UpdateWrapper<>();
        customerUpdateWrapper.set(Customer.COL_REALNAME_STATUS, status)
                .set(Customer.COL_REALNAME_TYPE, realnameType)
                .eq(Customer.COL_WX_ID, wxId);
        if (StringUtils.hasText(identity)) {
            customerUpdateWrapper.set(Customer.COL_IDENTITY, identity);
        }
        if (StringUtils.hasText(bankCard)) {
            customerUpdateWrapper.set(Customer.COL_BANK_CARD, bankCard);
        }
        super.update(customerUpdateWrapper);
    }

    /**
     * 推送实名认证链接
     * @param id
     * @param contractId
     */
    public void pushRealnameUrl(Long id, Long contractId) {
        Customer customer = super.getById(id);
        wechatApi.pushRealNameMsg(customer.getWxId(), customer.getName(), customer.getMobile());
        String contractIds = null;
        if (StringUtils.hasText(customer.getContractId())) {
            contractIds = customer.getContractId() + contractId + ",";
        } else {
            contractIds = "," + contractId.toString() + ",";
        }
        Customer updateEntity = new Customer();
        updateEntity.setId(customer.getId());
        updateEntity.setContractId(contractIds);
        super.updateById(updateEntity);
    }

    /**
     * 获取人脸识别结果
     * @param orderNo
     * @param sid
     */
    public Result<Void> getFaceResult(String orderNo, String sid) {
        Customer customer = getCustomerByWxId(sid);
        if (customer == null) {
            return Result.ERROR;
        }
        GetFaceAuthResultResponse getFaceAuthResultResponse = bestsignOpenApi.getFaceAuthResult(new GetFaceAuthResult(orderNo)).getData();
        if ("1".equals(getFaceAuthResultResponse.getVerifyResult())) {
            //认证成功
            updateRealnameStatusByWxId(1, sid, 3, null, null);
            asyncService.setPersonalCredential(getCustomerByWxId(sid));
            return Result.SUCCESS;
        } else {
            //认证失败
            updateRealnameStatusByWxId(2, sid, 0, null, null);
            return Result.ERROR;
        }
    }

    /**
     * 获取用户信息
     * @param bestsignAccount
     * @return
     */
    public Customer getByBestsignAccount(String bestsignAccount) {
        QueryWrapper<Customer> customerQueryWrapper = new QueryWrapper<>();
        customerQueryWrapper.eq(Customer.COL_ACCOUNT, bestsignAccount);
        return super.getOne(customerQueryWrapper);
    }

    /**
     * 判断用户是否关注
     * @param wxId
     * @return
     */
    public Boolean isSubscribe(String wxId) {
        String jsonStr = wechatApi.getWxUser(wxId);
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        return "1".equals(jsonObject.get("subscribe") + "");
    }
}
